/*
 * @Author: chengjiang
 * @Date: 2025-07-25 16:48:31
 * @Description:
 */
package server

import (
	"context"
	rhttp "net/http"

	"com.damai.services/common/auth"
	v1 "com.damai.services/gateway/api/helloworld/v1"
	"com.damai.services/gateway/internal/conf"
	"github.com/go-kratos/kratos/v2/middleware/circuitbreaker"

	// "com.damai.services/gateway/internal/middleware/breaker"
	"com.damai.services/gateway/internal/middleware/monitor"
	ratelimiter "com.damai.services/gateway/internal/middleware/rate_limiter"
	"com.damai.services/gateway/internal/service"
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/middleware"
	"github.com/go-kratos/kratos/v2/middleware/recovery"
	"github.com/go-kratos/kratos/v2/middleware/selector"
	"github.com/go-kratos/kratos/v2/transport/http"
)

var whiteList = map[string]bool{
	"/helloworld.Greeter/SayHello": true,
}

// NewHTTPServer new an HTTP server.
func NewHTTPServer(c *conf.Server,
	greeter *service.GreeterService,
	au auth.AuthRepo,
	logger log.Logger) *http.Server {
	consul := NewConsulService(c.Registry.Consul.Address)
	proxy := NewProxyHandler(consul)
	var opts = []http.ServerOption{
		http.Middleware(
			recovery.Recovery(),
			// circuitbreaker.Client(),
			selector.Server(
				au.Server(),
			).Match(auth.NewWhiteListMatcher(whiteList)).Build(),
			monitor.TracingMiddleware(),
			circuitbreaker.Client(),
			// breaker.NewBreakerMiddleware().GetBreaker(),
			// ratelimiter.NewRatelimitMiddleware(1, 1),
		),
	}
	if c.Http.Network != "" {
		opts = append(opts, http.Network(c.Http.Network))
	}
	if c.Http.Addr != "" {
		opts = append(opts, http.Address(c.Http.Addr))
	}
	if c.Http.Timeout != nil {
		opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
	}
	opts = append(opts, http.ResponseEncoder(auth.DefaultResponseEncoder), http.ErrorEncoder(auth.PHMDefaultErrorEncoder))
	srv := http.NewServer(opts...)
	//
	for _, route := range c.Gateway.Routes {
		mws := []middleware.Middleware{
			// breaker.NewBreakerMiddleware().GetBreaker(route.Upstream),
			ratelimiter.NewRatelimitMiddleware(int(route.RateLimit), int(route.RateLimit)),
		}
		if route.Auth {
			logger.Log(log.LevelDebug, "auth middleware", "enable")
			mws = append(mws, au.Server())
		}
		// chain := middleware.Chain(mws...)
		baseHandler := proxy.Proxy(route.Upstream)
		srv.HandlePrefix(route.Path, wrapMiddlewareToHTTP(mws, baseHandler, logger))
	}
	v1.RegisterGreeterHTTPServer(srv, greeter)
	return srv
}

func wrapMiddlewareToHTTP(
	mws []middleware.Middleware,
	proxyHandler rhttp.Handler,
	logger log.Logger,
) rhttp.Handler {
	// 构建中间件链
	chain := middleware.Chain(mws...)

	// 返回标准HTTP Handler
	return rhttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		logger.Log(log.LevelDebug, "proxying request", r.URL.Path)
		// 执行中间件链，中间件完成后执行代理转发
		_, err := chain(func(ctx context.Context, req interface{}) (interface{}, error) {
			// 中间件执行完毕，调用代理Handler转发请求
			proxyHandler.ServeHTTP(w, r) // 核心：转发到上游服务
			return nil, nil
		})(r.Context(), r)
		// 处理中间件执行过程中的错误
		if err != nil {
			logger.Log(log.LevelError, "middleware error", "error", err, "path", r.URL.Path)
			w.WriteHeader(rhttp.StatusInternalServerError)
			_, _ = w.Write([]byte("gateway error: " + err.Error()))
		}
		// proxyHandler.ServeHTTP(w, r)
	})
}

func GatewayAuthMiddleware(next rhttp.Handler) rhttp.Handler {
    return rhttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if r.Header.Get("X-Gateway-Auth") != "your-secret" {
            rhttp.Error(w, "Forbidden", rhttp.StatusForbidden)
            return
        }
        next.ServeHTTP(w, r)
    })
}